home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-02 / tpxms.zip / TPXMS.PAS < prev    next >
Pascal/Delphi Source File  |  1993-01-04  |  23KB  |  695 lines

  1. (****************************************************************************
  2.  
  3.           TPXMS.PAS  v1.00   Written by Vernon E. Davis   07/30/89
  4.  
  5.           for use with HIMEM.SYS, an Extended Memory Device Driver
  6.  
  7.  
  8.  NOTE: The current version of HIMEM.SYS ( v2.06 ), as of this release, does
  9.        not support the following Function Calls:
  10.  
  11.                  $0F : Reallocate Extended Memory Block
  12.                  $10 : Request Upper Memory Block
  13.                  $11 : Release Upper Memory Block
  14.  
  15.        This source code is written with these functions available, so when
  16.        HIMEM.SYS does support them, no recompilation will be necessary.
  17.  ****************************************************************************)
  18.  
  19. Unit TPXMS;
  20. Interface
  21. Uses
  22.    DOS;
  23. Type
  24.    Bit32Struct = LongInt;
  25.  
  26.    ExtMemMoveStruct =
  27.    Record
  28.       Length       : Bit32Struct;
  29.       SourceHandle : Word;
  30.       SourceOffset : Bit32Struct;
  31.       DestHandle   : Word;
  32.       DestOffset   : Bit32Struct
  33.    End;
  34.  
  35.    EMBHandleStruct =
  36.    Record
  37.       LockCount   : Byte;
  38.       FreeHandles : Byte;
  39.       BlockLenKB  : Word
  40.    End;
  41.  
  42.    UMBSegmentStruct =
  43.    Record
  44.       Segment   : Word;
  45.       UMBSizeKB : Word
  46.    End;
  47.  
  48. Var
  49.    isXMS       : Boolean;
  50.    XMSResult   : Word;
  51.    XMSError    : Byte;
  52.    XMM_Control : Array[0..1] of Word;
  53.  
  54. (* Procedure/Function Declarations *)
  55.  
  56.    Function  XMSErrorMsg : String;
  57.    Function  EXISTXMS : Boolean;
  58.    Procedure GetVerHiMem;
  59.    Procedure GetRevHiMem;
  60.    Procedure GetMemHMA(malloc : Word);
  61.    Procedure FreeMemHMA;
  62.    Procedure GlobalEnableA20;
  63.    Procedure GlobalDisableA20;
  64.    Procedure LocalEnableA20;
  65.    Procedure LocalDisableA20;
  66.    Procedure QueryA20;
  67.    Procedure QueryFreeMemXMS;
  68.    Procedure QueryFreeBlockXMS;
  69.    Function  AllocExtMemBlockXMS(malloc : Word) : Word;
  70.    Procedure FreeExtMemBlockXMS(handle : Word);
  71.    Procedure MoveExtMemBlockXMS(Var MoveStructure : ExtMemMoveStruct);
  72.    Function  LockExtMemBlockXMS(handle : Word) : Bit32Struct;
  73.    Procedure UnlockExtMemBlockXMS(handle : Word);
  74.    Procedure EMBHandleInfoXMS(handle : Word; Var HStructure : EMBHandleStruct);
  75.    Procedure ReallocExtMemBlockXMS(handle,KBsize : Word);
  76.    Procedure ReqUpperMemBlockUMB(malloc : Word; Var USeg : UMBSegmentStruct);
  77.    Procedure RelUpperMemBlockUMB(segment : Word);
  78.  
  79. Implementation
  80.  
  81. Function XMSErrorMsg : String;
  82. Var
  83.    XMSMsg : String;
  84. Begin
  85.    XMSMsg := '';
  86.    Case XMSError of
  87.    $00 : XMSMsg := '';
  88.    $80 : XMSMsg := '80 : XMS Function not implemented';
  89.    $81 : XMSMsg := '81 : VDISK detected';
  90.    $82 : XMSMsg := '82 : A20 Error';
  91.    $8E : XMSMsg := '8E : General Driver Error';
  92.    $8F : XMSMsg := '8F : Unrecoverable Driver Error';
  93.    $90 : XMSMsg := '90 : HMA does not exist';
  94.    $91 : XMSMsg := '91 : HMA in use by another process';
  95.    $92 : XMSMsg := '92 : Memory requested less than /HMAMIN= parameter';
  96.    $93 : XMSMsg := '93 : HMA not allocated';
  97.    $94 : XMSMsg := '94 : A20 is enabled';
  98.    $A0 : XMSMsg := 'A0 : All of Extended Memory is allocated';
  99.    $A1 : XMSMsg := 'A1 : No Extended Memory Handles available';
  100.    $A2 : XMSMsg := 'A2 : Extended Memory Handle is invalid';
  101.    $A3 : XMSMsg := 'A3 : Extended Move Structure: Source Handle is invalid';
  102.    $A4 : XMSMsg := 'A4 : Extended Move Structure: Source Offset is invalid';
  103.    $A5 : XMSMsg := 'A5 : Extended Move Structure: Destination Handle is invalid';
  104.    $A6 : XMSMsg := 'A6 : Extended Move Structure: Destination Offset is invalid';
  105.    $A7 : XMSMsg := 'A7 : Extended Move Structure: Length is invalid';
  106.    $A8 : XMSMsg := 'A8 : Extended Move Structure: Move has invalid overlap';
  107.    $A9 : XMSMsg := 'A9 : Parity Error';
  108.    $AA : XMSMsg := 'AA : Block is not locked';
  109.    $AB : XMSMsg := 'AB : Block is locked';
  110.    $AC : XMSMsg := 'AC : Block Lock Count has overflowed';
  111.    $AD : XMSMsg := 'AD : Block Lock has failed';
  112.    $B0 : XMSMsg := 'B0 : A smaller Upper Memory Block is available';
  113.    $B1 : XMSMsg := 'B1 : No Upper Memory Blocks are available';
  114.    $B2 : XMSMsg := 'B2 : Upper Memory Block Segment Number is invalid'
  115.    Else
  116.       XMSMsg := 'Unknown Error has occured'
  117.    End;
  118.    If XMSMsg <> '' Then
  119.       XMSErrorMsg := 'XMS Error $' + XMSMsg
  120. End;
  121.  
  122. Function EXISTXMS : Boolean;
  123. Var
  124.    regs : Registers;
  125. Begin
  126.    regs.AX := $4300;
  127.    Intr($2F,regs);
  128.    If regs.al = $80 Then
  129.    Begin
  130.       regs.AX := $4310;
  131.       Intr($2F,regs);
  132.       XMM_Control[0] := regs.bx;
  133.       XMM_Control[1] := regs.es;
  134.       EXISTXMS := TRUE
  135.    End
  136.    Else
  137.       EXISTXMS := FALSE
  138. End;
  139.  
  140. Procedure GetVerHiMem;
  141. (* XMSResult = Version level in BCD *)
  142. Var
  143.    ax : Word;
  144. Begin
  145.    XMSResult := 1;
  146.    XMSError  := 0;
  147.    If NOT isXMS Then
  148.    Begin
  149.       XMSResult := 0;
  150.       XMSError  := $80;
  151.       Exit
  152.    End;
  153.    Inline
  154.    (  $BF/XMM_Control/                     {  MOV  DI,XMM_Control        }
  155.       $B8/$00/$00/                         {  MOV  AX,0000               }
  156.       $55/                                 {  PUSH BP                    }
  157.       $FF/$1D/                             {  CALL FAR[DI] (XMM_Control) }
  158.       $5D/                                 {  POP  BP                    }
  159.       $89/$86/ax                           {  MOV  ax[BP],AX             }
  160.    );
  161.    XMSResult := ax
  162. End;
  163.  
  164. Procedure GetRevHiMem;
  165. (* XMSResult = Internal Revision level in BCD *)
  166. Var
  167.    bx : Word;
  168. Begin
  169.    XMSResult := 1;
  170.    XMSError  := 0;
  171.    If NOT isXMS Then
  172.    Begin
  173.       XMSResult := 0;
  174.       XMSError  := $80;
  175.       Exit
  176.    End;
  177.    Inline
  178.    (  $BF/XMM_Control/                     {  MOV  DI,XMM_Control        }
  179.       $B8/$00/$00/                         {  MOV  AX,0000               }
  180.       $55/                                 {  PUSH BP                    }
  181.       $FF/$1D/                             {  CALL FAR[DI] (XMM_Control) }
  182.       $5D/                                 {  POP  BP                    }
  183.       $89/$9E/bx                           {  MOV  bx[BP],BX             }
  184.    );
  185.    XMSResult := bx
  186. End;
  187.  
  188. Procedure GetMemHMA(malloc : Word);
  189. Var
  190.    ax : Word;
  191.    bl : Byte;
  192. Begin
  193.    XMSResult := 1;
  194.    XMSError  := 0;
  195.    If NOT isXMS Then
  196.    Begin
  197.       XMSResult := 0;
  198.       XMSError  := $80;
  199.       Exit
  200.    End;
  201.    Inline
  202.    (  $BF/XMM_Control/                     {  MOV  DI,XMM_Control        }
  203.       $8B/$96/malloc/                      {  MOV  DX,malloc[BP]         }
  204.       $B8/$00/$01/                         {  MOV  AX,0100               }
  205.       $55/                                 {  PUSH BP                    }
  206.       $FF/$1D/                             {  CALL FAR[DI] (XMM_Control) }
  207.       $5D/                                 {  POP  BP                    }
  208.       $89/$86/ax/                          {  MOV  ax[BP],AX             }
  209.       $88/$9E/bl                           {  MOV  bl[BP],BL             }
  210.    );
  211.    XMSResult := ax;
  212.    XMSError  := bl
  213. End;
  214.  
  215. Procedure FreeMemHMA;
  216. Var
  217.    ax : Word;
  218.    bl : Byte;
  219. Begin
  220.    XMSResult := 1;
  221.    XMSError  := 0;
  222.    If NOT isXMS Then
  223.    Begin
  224.       XMSResult := 0;
  225.       XMSError  := $80;
  226.       Exit
  227.    End;
  228.    Inline
  229.    (  $BF/XMM_Control/                     {  MOV  DI,XMM_Control        }
  230.       $B8/$00/$02/                         {  MOV  AX,0200               }
  231.       $55/                                 {  PUSH BP                    }
  232.       $FF/$1D/                             {  CALL FAR[DI] (XMM_Control) }
  233.       $5D/                                 {  POP  BP                    }
  234.       $89/$86/ax/                          {  MOV  ax[BP],AX             }
  235.       $88/$9E/bl                           {  MOV  bl[BP],BL             }
  236.    );
  237.    XMSResult := ax;
  238.    XMSError  := bl
  239. End;
  240.  
  241. Procedure GlobalEnableA20;
  242. Var
  243.    ax : Word;
  244.    bl : Byte;
  245. Begin
  246.    XMSResult := 1;
  247.    XMSError  := 0;
  248.    If NOT isXMS Then
  249.    Begin
  250.       XMSResult := 0;
  251.       XMSError  := $80;
  252.       Exit
  253.    End;
  254.    Inline
  255.    (  $BF/XMM_Control/                     {  MOV  DI,XMM_Control        }
  256.       $B8/$00/$03/                         {  MOV  AX,0300               }
  257.       $55/                                 {  PUSH BP                    }
  258.       $FF/$1D/                             {  CALL FAR[DI] (XMM_Control) }
  259.       $5D/                                 {  POP  BP                    }
  260.       $89/$86/ax/                          {  MOV  ax[BP],AX             }
  261.       $88/$9E/bl                           {  MOV  bl[BP],BL             }
  262.    );
  263.    XMSResult := ax;
  264.    XMSError  := bl
  265. End;
  266.  
  267. Procedure GlobalDisableA20;
  268. Var
  269.    ax : Word;
  270.    bl : Byte;
  271. Begin
  272.    XMSResult := 1;
  273.    XMSError  := 0;
  274.    If NOT isXMS Then
  275.    Begin
  276.       XMSResult := 0;
  277.       XMSError  := $80;
  278.       Exit
  279.    End;
  280.    Inline
  281.    (  $BF/XMM_Control/                     {  MOV  DI,XMM_Control        }
  282.       $B8/$00/$04/                         {  MOV  AX,0400               }
  283.       $55/                                 {  PUSH BP                    }
  284.       $FF/$1D/                             {  CALL FAR[DI] (XMM_Control) }
  285.       $5D/                                 {  POP  BP                    }
  286.       $89/$86/ax/                          {  MOV  ax[BP],AX             }
  287.       $88/$9E/bl                           {  MOV  bl[BP],BL             }
  288.    );
  289.    XMSResult := ax;
  290.    XMSError  := bl
  291. End;
  292.  
  293. Procedure LocalEnableA20;
  294. Var
  295.    ax : Word;
  296.    bl : Byte;
  297. Begin
  298.    XMSResult := 1;
  299.    XMSError  := 0;
  300.    If NOT isXMS Then
  301.    Begin
  302.       XMSResult := 0;
  303.       XMSError  := $80;
  304.       Exit
  305.    End;
  306.    Inline
  307.    (  $BF/XMM_Control/                     {  MOV  DI,XMM_Control        }
  308.       $B8/$00/$05/                         {  MOV  AX,0500               }
  309.       $55/                                 {  PUSH BP                    }
  310.       $FF/$1D/                             {  CALL FAR[DI] (XMM_Control) }
  311.       $5D/                                 {  POP  BP                    }
  312.       $89/$86/ax/                          {  MOV  ax[BP],AX             }
  313.       $88/$9E/bl                           {  MOV  bl[BP],BL             }
  314.    );
  315.    XMSResult := ax;
  316.    XMSError  := bl
  317. End;
  318.  
  319. Procedure LocalDisableA20;
  320. Var
  321.    ax : Word;
  322.    bl : Byte;
  323. Begin
  324.    XMSResult := 1;
  325.    XMSError  := 0;
  326.    If NOT isXMS Then
  327.    Begin
  328.       XMSResult := 0;
  329.       XMSError  := $80;
  330.       Exit
  331.    End;
  332.    Inline
  333.    (  $BF/XMM_Control/                     {  MOV  DI,XMM_Control        }
  334.       $B8/$00/$06/                         {  MOV  AX,0600               }
  335.       $55/                                 {  PUSH BP                    }
  336.       $FF/$1D/                             {  CALL FAR[DI] (XMM_Control) }
  337.       $5D/                                 {  POP  BP                    }
  338.       $89/$86/ax/                          {  MOV  ax[BP],AX             }
  339.       $88/$9E/bl                           {  MOV  bl[BP],BL             }
  340.    );
  341.    XMSResult := ax;
  342.    XMSError  := bl
  343. End;
  344.  
  345. Procedure QueryA20;
  346. (* XMSResult = 1 if A20 is physically enabled, else 0 *)
  347. Var
  348.    ax : Word;
  349. Begin
  350.    XMSResult := 1;
  351.    XMSError  := 0;
  352.    If NOT isXMS Then
  353.    Begin
  354.       XMSResult := 0;
  355.       XMSError  := $80;
  356.       Exit
  357.    End;
  358.    Inline
  359.    (  $BF/XMM_Control/                     {  MOV  DI,XMM_Control        }
  360.       $B8/$00/$07/                         {  MOV  AX,0700               }
  361.       $55/                                 {  PUSH BP                    }
  362.       $FF/$1D/                             {  CALL FAR[DI] (XMM_Control) }
  363.       $5D/                                 {  POP  BP                    }
  364.       $89/$86/ax                           {  MOV  ax[BP],AX             }
  365.    );
  366.    XMSResult := ax
  367. End;
  368.  
  369. Procedure QueryFreeMemXMS;
  370. (* XMSResult = total free Extended Memory in kilobytes *)
  371. Var
  372.    ax : Word;
  373. Begin
  374.    XMSResult := 1;
  375.    XMSError  := 0;
  376.    If NOT isXMS Then
  377.    Begin
  378.       XMSResult := 0;
  379.       XMSError  := $80;
  380.       Exit
  381.    End;
  382.    Inline
  383.    (  $BF/XMM_Control/                     {  MOV  DI,XMM_Control        }
  384.       $B8/$00/$08/                         {  MOV  AX,0800               }
  385.       $55/                                 {  PUSH BP                    }
  386.       $FF/$1D/                             {  CALL FAR[DI] (XMM_Control) }
  387.       $5D/                                 {  POP  BP                    }
  388.       $89/$86/ax                           {  MOV  ax[BP],AX             }
  389.    );
  390.    XMSResult := ax
  391. End;
  392.  
  393. Procedure QueryFreeBlockXMS;
  394. (* XMSResult = largest free block of Extended Memory in kilobytes *)
  395. Var
  396.    dx : Word;
  397. Begin
  398.    XMSResult := 1;
  399.    XMSError  := 0;
  400.    If NOT isXMS Then
  401.    Begin
  402.       XMSResult := 0;
  403.       XMSError  := $80;
  404.       Exit
  405.    End;
  406.    Inline
  407.    (  $BF/XMM_Control/                     {  MOV  DI,XMM_Control        }
  408.       $B8/$00/$08/                         {  MOV  AX,0800               }
  409.       $55/                                 {  PUSH BP                    }
  410.       $FF/$1D/                             {  CALL FAR[DI] (XMM_Control) }
  411.       $5D/                                 {  POP  BP                    }
  412.       $89/$96/dx                           {  MOV  dx[BP],DX             }
  413.    );
  414.    XMSResult := dx
  415. End;
  416.  
  417. Function AllocExtMemBlockXMS(malloc : Word) : Word;
  418. (* If successful, returns handle to Extended Memory Block *)
  419. Var
  420.    ax : Word;
  421.    dx : Word;
  422.    bl : Byte;
  423. Begin
  424.    XMSResult := 1;
  425.    XMSError  := 0;
  426.    If NOT isXMS Then
  427.    Begin
  428.       XMSResult := 0;
  429.       XMSError  := $80;
  430.       AllocExtMemBlockXMS := 0;
  431.       Exit
  432.    End;
  433.    Inline
  434.    (  $BF/XMM_Control/                     {  MOV  DI,XMM_Control        }
  435.       $8B/$96/malloc/                      {  MOV  DX,malloc[BP]         }
  436.       $B8/$00/$09/                         {  MOV  AX,0900               }
  437.       $55/                                 {  PUSH BP                    }
  438.       $FF/$1D/                             {  CALL FAR[DI] (XMM_Control) }
  439.       $5D/                                 {  POP  BP                    }
  440.       $89/$86/ax/                          {  MOV  ax[BP],AX             }
  441.       $88/$9E/bl/                          {  MOV  bl[BP],BL             }
  442.       $89/$96/dx                           {  MOV  dx[BP],DX             }
  443.    );
  444.    XMSResult := ax;
  445.    XMSError  := bl;
  446.    AllocExtMemBlockXMS := dx
  447. End;
  448.  
  449. Procedure FreeExtMemBlockXMS(handle : Word);
  450. Var
  451.    ax : Word;
  452.    bl : Byte;
  453. Begin
  454.    XMSResult := 1;
  455.    XMSError  := 0;
  456.    If NOT isXMS Then
  457.    Begin
  458.       XMSResult := 0;
  459.       XMSError  := $80;
  460.       Exit
  461.    End;
  462.    Inline
  463.    (  $BF/XMM_Control/                     {  MOV  DI,XMM_Control        }
  464.       $8B/$96/handle/                      {  MOV  DX,handle[BP]         }
  465.       $B8/$00/$0A/                         {  MOV  AX,0A00               }
  466.       $55/                                 {  PUSH BP                    }
  467.       $FF/$1D/                             {  CALL FAR[DI] (XMM_Control) }
  468.       $5D/                                 {  POP  BP                    }
  469.       $89/$86/ax/                          {  MOV  ax[BP],AX             }
  470.       $88/$9E/bl                           {  MOV  bl[BP],BL             }
  471.    );
  472.    XMSResult := ax;
  473.    XMSError  := bl
  474. End;
  475.  
  476. Procedure MoveExtMemBlockXMS(Var MoveStructure : ExtMemMoveStruct);
  477. (* NOTE: This procedure assumes that the ExtMemMove structure is valid *)
  478. Var
  479.    ax,
  480.    segs,
  481.    ofss : Word;
  482.    bl   : Byte;
  483. Begin
  484.    XMSResult := 1;
  485.    XMSError  := 0;
  486.    If NOT isXMS Then
  487.    Begin
  488.       XMSResult := 0;
  489.       XMSError  := $80;
  490.       Exit
  491.    End;
  492.    segs := Seg(MoveStructure);
  493.    ofss := Ofs(MoveStructure);
  494.    Inline
  495.    (  $1E/                                 {  PUSH DS                    }
  496.       $8B/$86/segs/                        {  MOV  AX,segs[BP]           }
  497.       $8E/$D8/                             {  MOV  DS,AX                 }
  498.       $8B/$B6/ofss/                        {  MOV  SI,ofss[BP]           }
  499.       $BF/XMM_Control/                     {  MOV  DI,XMM_Control        }
  500.       $B8/$00/$0B/                         {  MOV  AX,0B00               }
  501.       $55/                                 {  PUSH BP                    }
  502.       $FF/$1D/                             {  CALL FAR[DI] (XMM_Control) }
  503.       $5D/                                 {  POP  BP                    }
  504.       $1F/                                 {  POP  DS                    }
  505.       $89/$86/ax/                          {  MOV  ax[BP],AX             }
  506.       $88/$9E/bl                           {  MOV  bl[BP],BL             }
  507.    );
  508.    XMSResult := ax;
  509.    XMSError  := bl
  510. End;
  511.  
  512. Function LockExtMemBlockXMS(handle : Word) : Bit32Struct;
  513. Var
  514.    ax,bx,dx : Word;
  515. Begin
  516.    XMSResult := 1;
  517.    XMSError  := 0;
  518.    If NOT isXMS Then
  519.    Begin
  520.       XMSResult := 0;
  521.       XMSError  := $80;
  522.       LockExtMemBlockXMS := 0;
  523.       Exit
  524.    End;
  525.    Inline
  526.    (  $BF/XMM_Control/                     {  MOV  DI,XMM_Control        }
  527.       $8B/$96/handle/                      {  MOV  DX,handle[BP]         }
  528.       $B8/$00/$0C/                         {  MOV  AX,0C00               }
  529.       $55/                                 {  PUSH BP                    }
  530.       $FF/$1D/                             {  CALL FAR[DI] (XMM_Control) }
  531.       $5D/                                 {  POP  BP                    }
  532.       $89/$86/ax/                          {  MOV  ax[BP],AX             }
  533.       $89/$9E/bx/                          {  MOV  bx[BP],BX             }
  534.       $89/$96/dx                           {  MOV  dx[BP],DX             }
  535.    );
  536.    XMSResult := ax;
  537.    LockExtMemBlockXMS := (dx SHL 8) + bx
  538. End;
  539.  
  540. Procedure UnlockExtMemBlockXMS(handle : Word);
  541. Var
  542.    ax : Word;
  543.    bl : Byte;
  544. Begin
  545.    XMSResult := 1;
  546.    XMSError  := 0;
  547.    If NOT isXMS Then
  548.    Begin
  549.       XMSResult := 0;
  550.       XMSError  := $80;
  551.       Exit
  552.    End;
  553.    Inline
  554.    (  $BF/XMM_Control/                     {  MOV  DI,XMM_Control        }
  555.       $8B/$96/handle/                      {  MOV  DX,handle[BP]         }
  556.       $B8/$00/$0D/                         {  MOV  AX,0D00               }
  557.       $55/                                 {  PUSH BP                    }
  558.       $FF/$1D/                             {  CALL FAR[DI] (XMM_Control) }
  559.       $5D/                                 {  POP  BP                    }
  560.       $89/$86/ax/                          {  MOV  ax[BP],AX             }
  561.       $88/$9E/bl                           {  MOV  bl[BP],BL             }
  562.    );
  563.    XMSResult := ax;
  564.    XMSError  := bl
  565. End;
  566.  
  567. Procedure EMBHandleInfoXMS(handle : Word; Var HStructure : EMBHandleStruct);
  568. Var
  569.    ax,bx,dx : Word;
  570. Begin
  571.    XMSResult := 1;
  572.    XMSError  := 0;
  573.    If NOT isXMS Then
  574.    Begin
  575.       XMSResult := 0;
  576.       XMSError  := $80;
  577.       Exit
  578.    End;
  579.    Inline
  580.    (  $BF/XMM_Control/                     {  MOV  DI,XMM_Control        }
  581.       $8B/$96/handle/                      {  MOV  DX,handle[BP]         }
  582.       $B8/$00/$0E/                         {  MOV  AX,0E00               }
  583.       $55/                                 {  PUSH BP                    }
  584.       $FF/$1D/                             {  CALL FAR[DI] (XMM_Control) }
  585.       $5D/                                 {  POP  BP                    }
  586.       $89/$86/ax/                          {  MOV  ax[BP],AX             }
  587.       $89/$9E/bx/                          {  MOV  bx[BP],BX             }
  588.       $89/$96/dx                           {  MOV  dx[BP],DX             }
  589.    );
  590.    XMSResult := ax;
  591.    With HStructure Do
  592.    Begin
  593.       LockCount   := Hi(bx);
  594.       FreeHandles := Lo(bx);
  595.       BlockLenKB  := dx
  596.    End
  597. End;
  598.  
  599. Procedure ReallocExtMemBlockXMS(handle,KBsize : Word);
  600. Var
  601.    ax : Word;
  602.    bl : Byte;
  603. Begin
  604.    XMSResult := 1;
  605.    XMSError  := 0;
  606.    If NOT isXMS Then
  607.    Begin
  608.       XMSResult := 0;
  609.       XMSError  := $80;
  610.       Exit
  611.    End;
  612.    Inline
  613.    (  $BF/XMM_Control/                     {  MOV  DI,XMM_Control        }
  614.       $8B/$96/handle/                      {  MOV  DX,handle[BP]         }
  615.       $8B/$9E/KBSize/                      {  MOV  BX,KBSize[BP]         }
  616.       $B8/$00/$0F/                         {  MOV  AX,0F00               }
  617.       $55/                                 {  PUSH BP                    }
  618.       $FF/$1D/                             {  CALL FAR[DI] (XMM_Control) }
  619.       $5D/                                 {  POP  BP                    }
  620.       $89/$86/ax/                          {  MOV  ax[BP],AX             }
  621.       $88/$9E/bl                           {  MOV  bl[BP],BL             }
  622.    );
  623.    XMSResult := ax;
  624.    XMSError  := bl
  625. End;
  626.  
  627. Procedure ReqUpperMemBlockUMB(malloc : Word; Var USeg : UMBSegmentStruct);
  628. Var
  629.    ax,bx,dx : Word;
  630. Begin
  631.    XMSResult := 1;
  632.    XMSError  := 0;
  633.    If NOT isXMS Then
  634.    Begin
  635.       XMSResult := 0;
  636.       XMSError  := $80;
  637.       Exit
  638.    End;
  639.    Inline
  640.    (  $BF/XMM_Control/                     {  MOV  DI,XMM_Control        }
  641.       $8B/$96/malloc/                      {  MOV  DX,malloc[BP]         }
  642.       $B8/$00/$10/                         {  MOV  AX,1000               }
  643.       $55/                                 {  PUSH BP                    }
  644.       $FF/$1D/                             {  CALL FAR[DI] (XMM_Control) }
  645.       $5D/                                 {  POP  BP                    }
  646.       $89/$86/ax/                          {  MOV  ax[BP],AX             }
  647.       $89/$9E/bx/                          {  MOV  bx[BP],BX             }
  648.       $89/$96/dx                           {  MOV  dx[BP],DX             }
  649.    );
  650.    XMSResult := ax;
  651.    With USeg Do
  652.    Begin
  653.       Segment := bx;
  654.       If XMSResult = 1 Then
  655.          UMBSizeKB := malloc
  656.       Else
  657.          UMBSizeKB := dx
  658.    End
  659. End;
  660.  
  661. Procedure RelUpperMemBlockUMB(segment : Word);
  662. Var
  663.    ax : Word;
  664.    bl : Byte;
  665. Begin
  666.    XMSResult := 1;
  667.    XMSError  := 0;
  668.    If NOT isXMS Then
  669.    Begin
  670.       XMSResult := 0;
  671.       XMSError  := $80;
  672.       Exit
  673.    End;
  674.    Inline
  675.    (  $BF/XMM_Control/                     {  MOV  DI,XMM_Control        }
  676.       $8B/$96/segment/                     {  MOV  DX,segment[BP]        }
  677.       $B8/$00/$11/                         {  MOV  AX,1100               }
  678.       $55/                                 {  PUSH BP                    }
  679.       $FF/$1D/                             {  CALL FAR[DI] (XMM_Control) }
  680.       $5D/                                 {  POP  BP                    }
  681.       $89/$86/ax/                          {  MOV  ax[BP],AX             }
  682.       $88/$9E/bl                           {  MOV  bl[BP],BL             }
  683.    );
  684.    XMSResult := ax;
  685.    XMSError  := bl
  686. End;
  687.  
  688. Begin
  689.    XMM_Control[0] := 0;
  690.    XMM_Control[1] := 0;
  691.    XMSResult      := 1;
  692.    XMSError       := 0;
  693.    isXMS          := EXISTXMS;
  694. End.
  695.